home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termClip.c < prev    next >
C/C++ Source or Header  |  1995-02-15  |  8KB  |  465 lines

  1. /*
  2. **    termClip.c
  3. **
  4. **    Clipboard support routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12. STATIC struct IFFHandle    *ClipHandle;
  13. STATIC STRPTR         ClipBuffer,
  14.              ClipIndex;
  15. STATIC LONG         ClipSize,
  16.              ClipLength;
  17.  
  18.     /* CloseClip():
  19.      *
  20.      *    Close clipboard handle, stop reading.
  21.      */
  22.  
  23. VOID
  24. CloseClip()
  25. {
  26.     if(ClipHandle)
  27.     {
  28.         CloseIFF(ClipHandle);
  29.  
  30.         if(ClipHandle -> iff_Stream)
  31.             CloseClipboard((struct ClipboardHandle *)ClipHandle -> iff_Stream);
  32.  
  33.         FreeIFF(ClipHandle);
  34.  
  35.         ClipHandle = NULL;
  36.     }
  37.  
  38.     if(ClipBuffer)
  39.     {
  40.         FreeVecPooled(ClipBuffer);
  41.  
  42.         ClipBuffer = NULL;
  43.     }
  44. }
  45.  
  46.     /* GetClip(STRPTR Buffer,WORD Len,BYTE Filter):
  47.      *
  48.      *    Read text data from clipboard and put it into the supplied buffer.
  49.      */
  50.  
  51. WORD __regargs
  52. GetClip(STRPTR Buffer,WORD Len,BYTE Filter)
  53. {
  54.     WORD    BytesPut = 0;
  55.     UBYTE    c;
  56.  
  57.         /* Is the read buffer already exhausted? */
  58.  
  59.     if(!ClipLength)
  60.     {
  61.             /* Is there still any data to read? */
  62.  
  63.         if(ClipSize)
  64.         {
  65.             WORD Size = MIN(ClipSize,1024);
  66.  
  67.                 /* Try to read the data and return failure if necessary. */
  68.  
  69.             if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  70.                 return(-1);
  71.             else
  72.             {
  73.                 ClipSize    -= Size;
  74.                 ClipLength     = Size;
  75.                 ClipIndex     = ClipBuffer;
  76.             }
  77.         }
  78.         else
  79.         {
  80.                 /* We just parsed a single chunk, now go on and
  81.                  * look for another one.
  82.                  */
  83.  
  84.             if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  85.             {
  86.                 struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  87.  
  88.                 if(ContextNode -> cn_Type == ID_FTXT)
  89.                 {
  90.                     WORD Size;
  91.  
  92.                     ClipSize    = ContextNode -> cn_Size;
  93.                     Size        = MIN(ClipSize,1024);
  94.  
  95.                     if(ReadChunkBytes(ClipHandle,ClipBuffer,Size) != Size)
  96.                         return(-1);
  97.                     else
  98.                     {
  99.                         ClipSize    -= Size;
  100.                         ClipLength     = Size;
  101.                         ClipIndex     = ClipBuffer;
  102.                     }
  103.                 }
  104.                 else
  105.                     return(-1);
  106.             }
  107.             else
  108.                 return(-1);
  109.         }
  110.     }
  111.  
  112.     while(ClipLength && BytesPut < Len)
  113.     {
  114.         ClipLength--;
  115.  
  116.         switch(c = *ClipIndex++)
  117.         {
  118.             case '\r':
  119.  
  120.                 break;
  121.  
  122.             default:
  123.  
  124.                 if(IsPrintable[c])
  125.                 {
  126.                     *Buffer++ = c;
  127.                     BytesPut++;
  128.                 }
  129.  
  130.                 break;
  131.         }
  132.     }
  133.  
  134.     return(BytesPut);
  135. }
  136.  
  137.     /* OpenClip():
  138.      *
  139.      *    Open the clipboard for sequential reading.
  140.      */
  141.  
  142. BYTE __regargs
  143. OpenClip(LONG Unit)
  144. {
  145.     BYTE Error;
  146.  
  147.     CloseClip();
  148.  
  149.     if(ClipBuffer = (STRPTR)AllocVecPooled(1024,MEMF_ANY))
  150.     {
  151.         if(ClipHandle = AllocIFF())
  152.         {
  153.             if(ClipHandle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  154.             {
  155.                 InitIFFasClip(ClipHandle);
  156.  
  157.                 if(!OpenIFF(ClipHandle,IFFF_READ))
  158.                 {
  159.                     if(!StopChunk(ClipHandle,ID_FTXT,ID_CHRS))
  160.                     {
  161.                         if(!ParseIFF(ClipHandle,IFFPARSE_SCAN))
  162.                         {
  163.                             struct ContextNode *ContextNode = CurrentChunk(ClipHandle);
  164.  
  165.                             if(ContextNode -> cn_Type == ID_FTXT)
  166.                             {
  167.                                 ClipSize    = ContextNode -> cn_Size;
  168.                                 ClipLength    = 0;
  169.  
  170.                                 return(CLIPERR_NONE);
  171.                             }
  172.                             else
  173.                                 Error = CLIPERR_NOTEXT;
  174.                         }
  175.                         else
  176.                             Error = CLIPERR_NOTEXT;
  177.                     }
  178.                     else
  179.                         Error = CLIPERR_IFF;
  180.                 }
  181.                 else
  182.                     Error = CLIPERR_OPEN;
  183.             }
  184.             else
  185.                 Error = CLIPERR_OPEN;
  186.         }
  187.         else
  188.             Error = CLIPERR_MEM;
  189.     }
  190.     else
  191.         Error = CLIPERR_MEM;
  192.  
  193.     CloseClip();
  194.  
  195.     return(Error);
  196. }
  197.  
  198.     /* GetClipContents(LONG Unit,APTR *Buffer,LONG *Size):
  199.      *
  200.      *    Merge text contents of the clipboard into a single string.
  201.      */
  202.  
  203. BYTE __regargs
  204. GetClipContents(LONG Unit,APTR *Buffer,LONG *Size)
  205. {
  206.     struct IFFHandle    *Handle;
  207.     LONG             Bytes = 0;
  208.     APTR             Store = NULL;
  209.  
  210.     if(Handle = AllocIFF())
  211.     {
  212.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Unit))
  213.         {
  214.             InitIFFasClip(Handle);
  215.  
  216.             if(!OpenIFF(Handle,IFFF_READ))
  217.             {
  218.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  219.                 {
  220.                     struct ContextNode *Node;
  221.  
  222.                     while(!ParseIFF(Handle,IFFPARSE_SCAN))
  223.                     {
  224.                         Node = CurrentChunk(Handle);
  225.  
  226.                         if(Node -> cn_Type == ID_FTXT)
  227.                             Bytes += Node -> cn_Size;
  228.                     }
  229.                 }
  230.  
  231.                 CloseIFF(Handle);
  232.             }
  233.  
  234.             if(Bytes)
  235.             {
  236.                 if(!OpenIFF(Handle,IFFF_READ))
  237.                 {
  238.                     if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  239.                     {
  240.                         if(Store = AllocVecPooled(Bytes,MEMF_ANY))
  241.                         {
  242.                             STRPTR             Index        = Store;
  243.                             LONG             BytesRead    = 0;
  244.                             struct ContextNode    *Node;
  245.  
  246.                             while(!ParseIFF(Handle,IFFPARSE_SCAN) && BytesRead < Bytes)
  247.                             {
  248.                                 Node = CurrentChunk(Handle);
  249.  
  250.                                 if(Node -> cn_Type == ID_FTXT)
  251.                                 {
  252.                                     LONG Count = Node -> cn_Size;
  253.  
  254.                                     if(BytesRead + Count > Bytes)
  255.                                         Count = Bytes - BytesRead;
  256.  
  257.                                     if(Count > 0)
  258.                                     {
  259.                                         if((Count = ReadChunkBytes(Handle,Index,Count)) > 0)
  260.                                         {
  261.                                             Index        += Count;
  262.                                             BytesRead    += Count;
  263.                                         }
  264.                                     }
  265.                                 }
  266.                             }
  267.  
  268.                             Bytes = BytesRead;
  269.                         }
  270.                     }
  271.  
  272.                     CloseIFF(Handle);
  273.                 }
  274.             }
  275.  
  276.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  277.         }
  278.  
  279.         FreeIFF(Handle);
  280.     }
  281.  
  282.     if(Store && !Bytes)
  283.     {
  284.         FreeVecPooled(Store);
  285.  
  286.         Store = NULL;
  287.     }
  288.  
  289.     *Buffer    = Store;
  290.     *Size    = Bytes;
  291.  
  292.     return((BYTE)(Store != NULL));
  293. }
  294.  
  295.     /* AddClip(STRPTR Buffer,LONG Size):
  296.      *
  297.      *    Merge previous clipboard contents with new text,
  298.      *    then store the new string in the clipboard.
  299.      */
  300.  
  301. BYTE __regargs
  302. AddClip(STRPTR Buffer,LONG Size)
  303. {
  304.     LONG    Bytes;
  305.     APTR    Store;
  306.  
  307.     if(GetClipContents(Config -> ClipConfig -> ClipboardUnit,&Store,&Bytes))
  308.     {
  309.         struct IFFHandle    *Handle;
  310.         BYTE             Success = FALSE;
  311.  
  312.         if(Handle = AllocIFF())
  313.         {
  314.             if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  315.             {
  316.                 InitIFFasClip(Handle);
  317.  
  318.                 if(!OpenIFF(Handle,IFFF_WRITE))
  319.                 {
  320.                     if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  321.                     {
  322.                         if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  323.                         {
  324.                             if(WriteChunkBytes(Handle,Store,Bytes) == Bytes)
  325.                             {
  326.                                 if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  327.                                 {
  328.                                     if(!PopChunk(Handle))
  329.                                         Success = TRUE;
  330.                                 }
  331.                             }
  332.                         }
  333.                     }
  334.  
  335.                     if(Success)
  336.                     {
  337.                         if(PopChunk(Handle))
  338.                             Success = FALSE;
  339.                     }
  340.  
  341.                     CloseIFF(Handle);
  342.                 }
  343.  
  344.                 CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  345.             }
  346.  
  347.             FreeIFF(Handle);
  348.         }
  349.  
  350.         FreeVecPooled(Store);
  351.  
  352.         return(Success);
  353.     }
  354.     else
  355.         return(SaveClip(Buffer,Size));
  356. }
  357.  
  358.     /* SaveClip(STRPTR Buffer,LONG Size):
  359.      *
  360.      *    Send a given text buffer to the clipboard.
  361.      */
  362.  
  363. BYTE __regargs
  364. SaveClip(STRPTR Buffer,LONG Size)
  365. {
  366.     BYTE Success = FALSE;
  367.  
  368.     if(Size > 0)
  369.     {
  370.         struct IFFHandle *Handle;
  371.  
  372.         if(Handle = AllocIFF())
  373.         {
  374.             if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  375.             {
  376.                 InitIFFasClip(Handle);
  377.  
  378.                 if(!OpenIFF(Handle,IFFF_WRITE))
  379.                 {
  380.                     if(!PushChunk(Handle,ID_FTXT,ID_FORM,IFFSIZE_UNKNOWN))
  381.                     {
  382.                         if(!PushChunk(Handle,0,ID_CHRS,IFFSIZE_UNKNOWN))
  383.                         {
  384.                             if(WriteChunkBytes(Handle,Buffer,Size) == Size)
  385.                             {
  386.                                 if(!PopChunk(Handle))
  387.                                     Success = TRUE;
  388.                             }
  389.                         }
  390.                     }
  391.  
  392.                     if(Success)
  393.                     {
  394.                         if(PopChunk(Handle))
  395.                             Success = FALSE;
  396.                     }
  397.  
  398.                     CloseIFF(Handle);
  399.                 }
  400.  
  401.                 CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  402.             }
  403.  
  404.             FreeIFF(Handle);
  405.         }
  406.     }
  407.  
  408.     return(Success);
  409. }
  410.  
  411.     /* LoadClip(STRPTR Buffer,LONG Size):
  412.      *
  413.      *    Put the contents of the clipboard into a given
  414.      *    buffer. Note that only the first FTXT chunk will
  415.      *    be read. Since this code will only be called by
  416.      *    the clipboard server process which serves the
  417.      *    string gadget editing hook, this will hopefully
  418.      *    not be fatal. If you want more data to be read,
  419.      *    including multiple FTXT chunks, use the OpenClip(),
  420.      *    GetClip(), CloseClip() combo above.
  421.      */
  422.  
  423. LONG __regargs
  424. LoadClip(STRPTR Buffer,LONG Size)
  425. {
  426.     struct IFFHandle    *Handle;
  427.     LONG             Bytes = 0;
  428.  
  429.     if(Handle = AllocIFF())
  430.     {
  431.         if(Handle -> iff_Stream = (ULONG)OpenClipboard(Config -> ClipConfig -> ClipboardUnit))
  432.         {
  433.             InitIFFasClip(Handle);
  434.  
  435.             if(!OpenIFF(Handle,IFFF_READ))
  436.             {
  437.                 if(!StopChunk(Handle,ID_FTXT,ID_CHRS))
  438.                 {
  439.                     if(!ParseIFF(Handle,IFFPARSE_SCAN))
  440.                     {
  441.                         struct ContextNode *ContextNode = CurrentChunk(Handle);
  442.  
  443.                         if(ContextNode -> cn_Type == ID_FTXT)
  444.                         {
  445.                             if(Size > ContextNode -> cn_Size)
  446.                                 Size = ContextNode -> cn_Size;
  447.  
  448.                             if(ReadChunkRecords(Handle,Buffer,Size,1))
  449.                                 Bytes = Size;
  450.                         }
  451.                     }
  452.                 }
  453.  
  454.                 CloseIFF(Handle);
  455.             }
  456.  
  457.             CloseClipboard((struct ClipboardHandle *)Handle -> iff_Stream);
  458.         }
  459.  
  460.         FreeIFF(Handle);
  461.     }
  462.  
  463.     return(Bytes);
  464. }
  465.